#include "stm32f10x.h"
#include "IR.h"
#include "Serial.h"
#include "OLED.h"
#include "Delay.h"
#define BUF_MAX 1024
void IR_Receive_Init(void)
{
	//以上为外部中断接受硬件解调后的红外信号
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//GPIOB0 -> AFIO的第0个数据选择器  (->  EXTI0)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0); 
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	//EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  //下降沿触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3使能
	TIM_InternalClockConfig(TIM3); //选择内部时钟作为时钟源，可省略
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //滤波采样分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 65536-1; //ARR自动重装器的值 
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1; //PSC预分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器，先不用管
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); //增长间隔为0.000001s (1us)
	 //启动计时器
	TIM_Cmd(TIM3,ENABLE);
}

void IR_Send_Init(void) //38.095khz A0
{
	//以下为调制并发送红外信号
	//启用GPIOA0
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //TIM2使能
	TIM_InternalClockConfig(TIM2); //选择内部时钟作为时钟源，可省略
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //滤波采样分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 105-1; //ARR自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 18-1; //PSC预分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器，先不用管
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure); //给结构体赋初值
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //极性 不 翻转,使得ccr为0时输出低电平
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0; //CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);
	
	TIM_Cmd(TIM2,ENABLE); //启动计时器
}
#define STATUS_FREE 0
#define STATUS_START 1
unsigned int que[BUF_MAX];
int signCount = 0;
int StatusCode = STATUS_FREE;

void Print_QUe(void)
{
	int i;
	Serial_SendByte('<');
	Serial_Printf("(%03d)",signCount);
	for(i=0;i<signCount;i++) {
		Serial_Printf("%2d ",que[i]);
	}
	Serial_SendByte('>');
	Serial_SendByte('\r');
	Serial_SendByte('\n');
}

void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) != SET)
		return;
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0) {
		//OLED_ShowNum(2,1,signCount,8);
		//int time = 0;
		switch(StatusCode) {
			case STATUS_FREE:
				TIM_SetCounter(TIM3,0);
				StatusCode = STATUS_START;
			break;
			case STATUS_START:
				if(signCount == BUF_MAX-1) break;
				que[signCount] = TIM_GetCounter(TIM3);
				signCount++;
				TIM_SetCounter(TIM3,0);
			break;
		}
	} else if(StatusCode == STATUS_START) {
		if(signCount == BUF_MAX-1) return;
				que[signCount] = TIM_GetCounter(TIM3);
				signCount++;
				TIM_SetCounter(TIM3,0);
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}


void IR_Enlight(void) {
	TIM_SetCompare1(TIM2,52);
}

void IR_Dislight(void) {
	TIM_SetCompare1(TIM2,0);
}

void IR_SendStringBits(char *str) { //如字符串'01001110"
	while(*str) {
		IR_SendBit(*str & 0x0f);
		str++;
	}
}

void IR_SendArrayBits(char *arr,int len) {
	int i;
	for(i=0;i<len;i++) {
		IR_SendBit(arr[i]);
	}
}

void IR_SendHigh(void) { //注意，对于接收方来说，SendHigh会在红外接受器中收到低电平
	IR_Enlight();
	Delay_us(680);
	IR_Dislight();
	Delay_us(1630);
}

void IR_SendLow(void) {
	IR_Enlight();
	Delay_us(680);
	IR_Dislight();
	Delay_us(510);
}

void IR_SendBit(char bit) {
	bit ? IR_SendHigh() : IR_SendLow();
}

void IR_SendHead(void) {
	IR_Enlight();
	Delay_us(9010);
	IR_Dislight();
	Delay_us(4505);
}

void IR_SendCat(void) {
	IR_Enlight();
	Delay_us(680);
	IR_Dislight();
	Delay_us(19975);
}

void IR_SendLongCat(void) {
	IR_Enlight();
	Delay_us(680);
	IR_Dislight();
	Delay_us(39950);
}
